﻿//Copyright (C) <2013>  <jonathan cleeve norton> All Rights Reserved 
//Contact jon.norton@fin-plus.co.uk website <http://www.fin-plus.co.uk/>
using System;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Reflection;
using FinPlusCommon;
using Microsoft.Win32;
using u = FinPlusUtility.Utility;
using log = Logger.Logger;

namespace FinPlusWPFControls
{
    public partial class FinPlusConfigCheck : FinPlusControl
    {
        public override string[] States { get { return new string[] { "FilePath", "Height", "Width", "Left", "Top", "InfoState" }; } }
        public override string[] TestStates { get { return new string[] { "TestString", "IsValid", "FilePath" }; } }
        public string FilePath { get { return _filePath; } set { _filePath = value; tFile.Text = _filePath; } }
        public string ConfigType { 
            get 
            { 
                return _configType.ToString(); 
            }
            set
            {
                _configType = u.EnumParse<ConfigTypes>(value, ConfigTypes.View); 
                cConfigType.Text = _filePath; 
            }
        }
        public string InfoState { get { return GetInfoState(); } set { SetInfoState(value); } }

        private enum ConfigTypes { View, Service, State };
        private const string XmlNode = "root/current";
        private const string ComponentAssembly = "finpluscomponents";
  
        private IFunctions _template = new Functions();
        private IFunction _infoParent;
        private ConfigTypes _configType;
        private Assembly _target;
        private string _filePath, _infoPath, _serviceName;
  
        //construct
        public FinPlusConfigCheck()
        {
            InitializeComponent();
            cConfigType.ItemsSource = Enum.GetValues(typeof(ConfigTypes)).Cast<ConfigTypes>();
            cConfigType.SelectedItem = ConfigTypes.View;
            IsValid = true;
        }

        //common control interface
        public override void CmdExecute(IFunction command)
        {
            try
            {
                CmdCapture(command);

                switch ((Cmds)Enum.Parse(typeof(Cmds), command.Name, true))
                {
                    case Cmds.Refresh: FileConnect(tFile.Text); break;
                    case Cmds.Cancel: Clear(); break;
                    case Cmds.Play: Play(); break;
                    case Cmds.Stop: ClearChildren(); break;
                    case Cmds.File: FileLoad(command["Tag"].ToString()); break;
                    default: throw new Exception(string.Format("event not recognised {0}", command.Name));
                }
            }
            catch (CmdExecuteException e)
            {
                IsValid = log.Log(Logger.Level.Warning, Id, Config, e.Message, e);
            }
        }

        public override void Dispose()  
        {
            if(_template != null)
                FinPlusDInject.Get.Dispose(_template);
        }

        //private
        private void AddConnection(IFinPlusComp conn)
        {
            try
            {
                Clear();
                _template = conn.Adaptor;
                xmlLayout.xmlDocument = _template.ToXmlDoc();
                ShowInfos(_template, _target);
            }
            catch (Exception e)
            {
                gridUI.Children.Add(new FinPlusErrorDisplay(e));
                log.Log(Logger.Level.Error, Id, Config, e.Message, e);
            }
        }

        private void ClearChildren()
        {
            testSubject.Text = "";
            gridUI.Children.Clear();
        }

        private void Play()
        {
            try
            {
                if (string.IsNullOrEmpty(_filePath)) return;

                _serviceName = _filePath.Split('\\').Last();
                gridUI.Children.Clear();
                _configType = (ConfigTypes)cConfigType.SelectedItem;
                _target = _configType == ConfigTypes.View ? Assembly.GetExecutingAssembly() : Assembly.LoadFile(u.GetAssemblyPath(Assembly.GetExecutingAssembly()) + ComponentAssembly + ".dll");

                FinPlusDInject.Get.Dispose(_template);
                var parent = FinPlusDInject.Get.Construct(_template, _serviceName.Split('.')[0], u.Env.dev);

                ShowInfos(_template, _target);

                if (_configType == ConfigTypes.Service)
                    ShowService(parent);
                else if (_configType == ConfigTypes.View)
                    ShowView(parent);

                testSubject.Text = _serviceName;
            }
            catch (Exception e)
            {
                IsValid = log.Log(Logger.Level.Warning, Id, Config, e.Message, e);
            }
        }

        private void ShowInfos(IFunctions funcs, Assembly target)
        {
            var infos = FuncInfos.Get(funcs, target);

            var funcDynamics = new FuncDynamics(infos);
            var filterTray = new FinPlusFilterbarTray() { Id = "InfoFilterbarTray" };
            var colTypes = u.StringToDictOfArrays("{{Exclude,{TimeStamp,FunctionName}},{ValueFunction,{Function,Methods,Properties}},{ValueTriState,{IsBuilt,IsValid}}}", ',', "{}");
            var colhelper = new FinPlusGridColHelper(null, colTypes, new string[]{"Function","Methods","Properties"}, null);
            var dataGrid = new FinPlusGroupGrid(new object[]{ funcDynamics, filterTray}, colhelper, true, false) { Id = "InfoGrid" };

            _infoParent = new Function() { Object = dataGrid };

            SetInfoState(_infoPath);
            gridInfos.Children.Add(dataGrid);
        }

        private void ShowService(IFunction parentFunc)
        {
            var funcDynamics = new FuncDynamics(((IFinPlusComp)parentFunc.Object).Adaptor);
            var filterTray = new FinPlusFilterbarTray() { Id = "InfoFilterbarTray" };
            var colhelper = new FinPlusGridColHelper(null, null, null, null);
            var dataGrid = new FinPlusGroupGrid(new object[] { funcDynamics, filterTray }, colhelper, true, false);

            gridUI.Children.Add(dataGrid);
        }

        private void ShowView(IFunction parentFunc)
        {
            FinPlusDInject.Get.InjectStates(parentFunc, new Functions(_filePath.ToLower().Replace(".view", ".state"), XmlNode));
            gridUI.Children.Add((UserControl)parentFunc.Object);
        }

        private string GetInfoState()
        {
            if (_infoParent == null) 
                return string.Empty;

            var path = u.GetAssemblyPath(Assembly.GetExecutingAssembly()) + "FinPlusViews\\InfoState.State";
            FinPlusDInject.Get.ExtractStates(_infoParent, Environment.UserName).ToXmlDoc(XmlNode).Save(path);
            return path;
        }

        private void SetInfoState(string path)
        {
            if (!string.IsNullOrEmpty(path))
                FinPlusDInject.Get.InjectStates(_infoParent, new Functions(_infoPath = path, XmlNode));
        }

        private void FileLoad(string path)
        {
            tFile.Text = _filePath = path;
            FileConnect(tFile.Text);
        }

        private void FileConnect(string path, string serviceType = "test", string serviceName = "test")
        {
            var service = new FinPlusConnectXML(serviceType, serviceName, string.Empty, path, XmlNode, false, true);
            AddConnection(service);;
        }

        private void Clear()
        {
            try
            {
                xmlLayout.xmlDocument = null;
                gridUI.Children.Clear();
                ShowInfos(_template, _target);
            }
            catch (Exception e)
            {
                log.Log(Logger.Level.Error, Id, Config, e.Message, e);
            }
        }

        private void FileRouter(string command)
        {
            gridUI.Children.Clear();
            var d = new OpenFileDialog()
            {
                FileName = "Document",
                DefaultExt = "." + cConfigType.SelectedItem,
                Filter = string.Format("{0} documents (.{0})|*.{0}", cConfigType.SelectedItem)
            };
            var res = d.ShowDialog();

            if (res == true)
                CmdExecute(new Function(command, Id, User, -1, d.FileName));
        }

        //cmds
        private enum Cmds { Refresh, Cancel, Play, Stop, File }
    }
}





























































































//Copyright2013<jnrton>AllRightsReserved 
//Contact j.nrton@finpus